import * as THREE from 'three'
import { color } from '../config'
export class Fly {
  constructor(scene, time) {
    this.scene = scene
    this.time = time
    this.createFly({
      // 起始点
      source: {
        x: 300,
        y: 0,
        z: -200
      },
      // 终止点
      target: {
        x: -500,
        y: 0,
        z: -240
      },
      // 飞线长度
      range: 200,
      height: 300,
      color: color.fly,
      size: 30 // 飞线大小
    })
  }
  createFly(options) {
    const source = new THREE.Vector3(
      options.source.x,
      options.source.y,
      options.source.z
    )
    const target = new THREE.Vector3(
      options.target.x,
      options.target.y,
      options.target.z
    )
    // 通过起始点终止点计算中心位置
    const center = target.clone().lerp(source, 0.5)
    // 设置中心位置的高度
    center.y += options.height
    // 起始点到终止点的距离
    const len = parseInt(source.distanceTo(target))
    // 添加贝塞尔曲线运动
    const curve = new THREE.QuadraticBezierCurve3(source, center, target)
    // 获取需要的粒子
    const points = curve.getPoints(len)
    // 粒子坐标集合
    const positions = []
    // 粒子下标
    const aPositions = []
    points.forEach((item, index) => {
      positions.push(item.x, item.y, item.z)
      aPositions.push(index)
    })
    const geometery = new THREE.BufferGeometry()
    geometery.setAttribute(
      'position',
      new THREE.Float32BufferAttribute(positions, 3)
    )
    geometery.setAttribute(
      'a_position',
      new THREE.Float32BufferAttribute(aPositions, 1)
    )
    const material = new THREE.ShaderMaterial({
      uniforms: {
        u_color: {
          value: new THREE.Color(options.color)
        },
        u_range: {
          value: options.range
        },
        u_size: {
          value: options.size
        },
        u_total: {
          value: len
        },
        u_time: this.time
      },
      vertexShader: `
        attribute float a_position;
        uniform float u_time;
        uniform float u_size;
        uniform float u_range;
        uniform float u_total;
        varying float v_opacity;
        void main () {
          float size = u_size; // 飞线大小
          float total_number = u_total * mod(u_time, 1.0);
          if (total_number > a_position && total_number < a_position + u_range) {
            // 拖尾效果
            float index = (a_position + u_range - total_number) / u_range;
            size *= index;
            v_opacity = 1.0;
          } else {
            v_opacity = 0.0;
          }
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
          gl_PointSize = size / 10.0;
        }
      `,
      fragmentShader: `
        uniform vec3 u_color;
        varying float v_opacity;
        void main () {
          gl_FragColor = vec4(u_color, v_opacity);
        }
      `,
      transparent: true
    })
    const point = new THREE.Points(geometery, material)
    this.scene.add(point)
  }
}
